///////////////////////////////////////////////////////////////////////////////
////  (c) Chaichuk AU (chaichuk@mail.ru), 								   ////
////  2005, Chelyabinsk, NTC Privodnaya Tehnika (momentum@chel.surnet.ru)  ////
///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>

#include "anybus_dpm.h"

//----------------------------------------------------------------------------
int abs_dpm_init (abs_module_t *abs, uint16_t dpram_mode, uint16_t startup_mode)
{
	uint16_t msg_id;
	uint16_t fault_info;
	const uint8_t fb_init_msg []   	= { 0x40, 0x02, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00};
	uint8_t fb_init_data [6];
	uint8_t fb_init_resp [14];
	uint8_t fb_init_resp_ext [16];
	uint8_t fb_init_resp_data [6];		
	
	fb_init_data [0] = (uint8_t) (dpram_mode >> 8);
	fb_init_data [1] = (uint8_t) (dpram_mode >> 0);
	fb_init_data [2] = 0x00;
	fb_init_data [3] = 0x0C;
	fb_init_data [4] = (uint8_t) (startup_mode >> 8);	
	fb_init_data [5] = (uint8_t) (startup_mode >> 0);	

	//abs_print_msg (fb_init_data, 6);
		
	do {
		abs_update_status (abs);	
	} while (abs_send_mbx_msg (abs, &msg_id, fb_init_msg, NULL, fb_init_data) == -1);
	do {
		abs_update_status (abs);
	} while (abs_recv_mbx_msg (abs, msg_id, fb_init_resp, fb_init_resp_ext, fb_init_resp_data, 6) == -1);
	if (fb_init_resp [0] & 0x80) {
		fprintf (stderr, "fb_init_resp error (code = 0x%X)!\n", fb_init_resp [0]);
		if ((fb_init_resp [0] & 0x0F) == 0x0F) {
			fault_info = (fb_init_resp_ext [14] << 8) + fb_init_resp_ext [15];
			printf ("fb_init error: ");
			switch (fault_info) {
				case 1:	printf ("invalid 'DPRAM mode' setting\n"); break;
				case 2:	printf ("invalid 'Special functions' setting\n"); break;
				case 3:	printf ("invalid 'Start-up operation mode' setting\n"); break;				
				case 4:	printf ("command not allowed after ANYBUS_INIT\n"); break;
				case 5:	printf ("command not allowed after END_INIT\n"); break;	
				case 6:	printf ("command not allowed before START_INIT\n"); break;
			}			
		}
		return -1;
	}
	
	return 0;	
}

//----------------------------------------------------------------------------
int abs_dpm_get_db_info (abs_module_t *abs, uint16_t *total_input_len,	uint16_t *total_output_len, 
							uint16_t *init_input_len, uint16_t *init_output_len)
{
	uint16_t msg_id;
	uint16_t fault_info;	
	const uint8_t get_db_info_msg []   	= { 0x40, 0x02, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00};
	uint8_t get_db_info_resp [14];
	uint8_t get_db_info_resp_ext [16];
	char get_db_info_resp_data [65];	
	
	do {
		abs_update_status (abs);	
	} while (abs_send_mbx_msg (abs, &msg_id, get_db_info_msg, NULL, NULL) == -1);
	do {
		abs_update_status (abs);
	} while (abs_recv_mbx_msg (abs, msg_id, get_db_info_resp, get_db_info_resp_ext, get_db_info_resp_data, 64) == -1);
	if (get_db_info_resp [0] & 0x80) {
		fprintf (stderr, "get_db_info_resp error (code = 0x%X)!\n", get_db_info_resp [0]);
		if ((get_db_info_resp [0] & 0x0F) == 0x0F) {
			fault_info = (get_db_info_resp_ext [14] << 8) + get_db_info_resp_ext [15];			
			printf ("fb_get_db_info error: ");
				switch (fault_info) {
				case 1:	printf ("no database in flash, or download in progress\n"); break;
			}
		}
		return -1;
	}
	
	*total_input_len  = (get_db_info_resp_ext [0] << 8) + get_db_info_resp_ext [1];
	*total_output_len = (get_db_info_resp_ext [2] << 8) + get_db_info_resp_ext [3];
	*init_input_len   = (get_db_info_resp_ext [4] << 8) + get_db_info_resp_ext [5];
	*init_output_len  = (get_db_info_resp_ext [6] << 8) + get_db_info_resp_ext [7];
				
	printf ("total input length  = %hd bytes\n", *total_input_len);
	printf ("total output length = %hd bytes\n", *total_output_len);	
	printf ("init input length   = %hd bytes\n", *init_input_len);
	printf ("init output length   = %hd bytes\n", *init_output_len);
	
	return 0;
}

